package com.xique.door.project.miniprogram.biz.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSONObject;
import com.xique.common.core.domain.R;
import com.xique.common.core.utils.*;
import com.xique.common.core.web.domain.AjaxResult;
import com.xique.common.redis.service.RedisService;
import com.xique.door.bean.dao.BuildHouseUserDAO;
import com.xique.door.bean.domain.AccessDevice;
import com.xique.door.bean.domain.User;
import com.xique.door.bean.domain.UserDevice;
import com.xique.door.bean.domain.UserV1;
import com.xique.door.bean.request.visitor.VisitorAddRequest;
import com.xique.door.biz.service.IVisitorBizService;
import com.xique.door.constant.AccessDeviceConstant;
import com.xique.door.constant.DoorDeviceConstant;
import com.xique.door.constant.VisitorConstants;
import com.xique.door.project.miniprogram.bean.request.MiniVisitorCompleteInviteRequest;
import com.xique.door.project.miniprogram.bean.request.MiniVisitorInviteRequest;
import com.xique.door.project.miniprogram.bean.vo.MiniInvitationCodeVO;
import com.xique.door.project.miniprogram.biz.service.IMiniVisitorBizService;
import com.xique.door.service.IAccessDeviceService;
import com.xique.door.service.IBuildHouseUserService;
import com.xique.door.service.IUserDeviceService;
import com.xique.door.service.IUserService;
import com.xique.door.util.QRCodeUtils;
import com.xique.system.api.RemoteSystemProjectService;
import com.xique.system.api.dto.SystemProjectDTO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @author shd
 * @create 2022/4/21 9:12
 */
@Service
public class MiniVisitorBizServiceImpl implements IMiniVisitorBizService {

    @Autowired
    private IUserService userService;

    @Autowired
    private IAccessDeviceService accessDeviceService;

    @Autowired
    private RemoteSystemProjectService projectService;

    @Autowired
    private AliossUtil aliossUtil;

    @Value("${visitor.url}")
    private String visitorUrl;

    @Autowired
    private RedisService redisService;

    @Autowired
    private IVisitorBizService visitorBizService;

    @Autowired
    private IBuildHouseUserService houseUserService;

    @Autowired
    private IUserDeviceService userDeviceService;

    @Override
    public AjaxResult getInvitationCode() {
        Long baseUserId = SecurityUtils.getBaseUserId();
        if (StringUtils.isNull(baseUserId)) {
            return AjaxResult.error("请登录");
        }
        //        Long parkId = SecurityUtils.getParkId();
        //        if (StringUtils.isNull(parkId)) {
        //            return AjaxResult.error("请选择小区");
        //        }
        //        Long userId = SecurityUtils.getUserId();
        //        if (StringUtils.isNull(userId)) {
        //            return AjaxResult.error("您不属于该小区", Collections.singletonMap("list", new
        // ArrayList()));
        //        }
        User user1 = new User();
        user1.setBaseUserId(baseUserId);
        List<User> listuser = userService.selectUserList(user1);
        List<MiniInvitationCodeVO> vos = new ArrayList<>();
        listuser.forEach(
                item -> {
                    User user = userService.selectUserById(item.getId());
                    String code = user.getInvitationCode();
                    if (StringUtils.isNull(code)) {
                        code = createInvitationCode(user.getParkId());
                        User update = new User();
                        update.setId(item.getId());
                        update.setInvitationCode(code);
                        update.setUpdateUser(item.getId());
                        update.setUserType(1);
                        update.setUpdateUser(SecurityUtils.getBaseUserId());
                        user.setInvitationCode(code);
                    }

                    UserDevice search = new UserDevice();
                    search.setUserId(item.getId());
                    List<UserDevice> list = userDeviceService.selectUserDeviceList(search);
                    List<Long> deviceIds =
                            list.stream().map(UserDevice::getDeviceId).distinct().collect(Collectors.toList());

                    List<AccessDevice> deviceList = accessDeviceService.selectAccessDeviceByIds(deviceIds);
                    List<String> deviceNames =
                            deviceList.stream()
                                    .filter(
                                            v ->
                                                    (DoorDeviceConstant.DeviceModel.QST_32.equals(v.getModel())
                                                            || DoorDeviceConstant.DeviceModel.QST_45.equals(v.getModel())))
                                    .filter(v -> AccessDeviceConstant.DeviceStatus.NORMAL.equals(v.getStatus()))
                                    .map(AccessDevice::getName)
                                    .collect(Collectors.toList());

                    MiniInvitationCodeVO vo = new MiniInvitationCodeVO();
                    vo.setCode(user.getInvitationCode());
                    vo.setDeviceNames(deviceNames);

                    R<SystemProjectDTO> result = projectService.getProjectInfo(user.getParkId());
                    if (R.SUCCESS == result.getCode()) {
                        SystemProjectDTO dto = result.getData();
                        vo.setParkId(dto.getId());
                        vo.setParkName(dto.getName());
                    }

                    GregorianCalendar calendar = new GregorianCalendar();
                    int hour = calendar.get(Calendar.HOUR_OF_DAY);
                    int startTime = hour / 3 * 3;
                    int endTime = hour / 3 * 3 + 3;
                    vo.setStartTime(startTime + ":00");
                    vo.setEndTime(endTime + ":00");
                    if (deviceNames.size() > 0) {
                        vos.add(vo);
                    }
                });
        return AjaxResult.success(Collections.singletonMap("list", vos));
    }

    private String createInvitationCode(Long parkId) {
        String code = MathUtil.getRandom(6);
        boolean flag = true;
        while (flag) {
            flag = userService.checkInvitationCode(parkId, code);
            if (!flag) {
                break;
            }
            code = MathUtil.getRandom(6);
        }
        return code;
    }

    @Override
    public AjaxResult invite(MiniVisitorInviteRequest request) throws Exception {
        Long baseUserId = SecurityUtils.getBaseUserId();
        if (StringUtils.isNull(baseUserId)) {
            return AjaxResult.error("请登录");
        }
//    Long parkId = SecurityUtils.getParkId();
//    if (StringUtils.isNull(parkId)) {
//      return AjaxResult.error("请选择小区");
//    }
//    Long userId = SecurityUtils.getUserId();
//    if (StringUtils.isNull(userId)) {
//      return AjaxResult.error("您不属于该小区");
//    }


        UserV1 listuser = userService.seleceteUserV(baseUserId, request.getParkId(), request.getHouseId());

        //User user = userService.selectUserById(userId);
        if (StringUtils.isNull(listuser)) {
            return AjaxResult.error("未找到对应用户");
        }
        request.setUserId(listuser.getId());
        String customerId = System.currentTimeMillis() + MathUtil.getRandom(10);
        String url = visitorUrl + "a=1&visitorId=" + customerId;

        ByteArrayOutputStream output = new ByteArrayOutputStream();
        QRCodeUtils.encode(url, output);

        ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(output.toByteArray());
        Map<String, Object> map = aliossUtil.uploadByByteArray(byteArrayInputStream);

        url = (String) map.get("url");

        redisService.setCacheObject(
                "inviteVisitor:" + customerId,
                JSONObject.toJSONString(request),
                (long) 60 * 60 * 2,
                TimeUnit.SECONDS);

        return AjaxResult.success("成功", url);
    }

    @Override
    public AjaxResult completeInvite(MiniVisitorCompleteInviteRequest request) {

        String visitorInfo = redisService.getCacheObject("inviteVisitor:" + request.getVisitorId());
        if (StringUtils.isEmpty(visitorInfo)) {
            return AjaxResult.error("该二维码已失效");
        }
        MiniVisitorInviteRequest visitorInfoRequest =
                JSONObject.parseObject(visitorInfo, MiniVisitorInviteRequest.class);

        VisitorAddRequest addRequest = OrikaUtil.convert(visitorInfoRequest, VisitorAddRequest.class);

        List<BuildHouseUserDAO> houseUserList =
                houseUserService.selectBuildHouseUserByUserIdAndHouseId(
                        addRequest.getUserId(), addRequest.getHouseId());
        if (CollectionUtil.isEmpty(houseUserList)) {
            return AjaxResult.error("未找到对应用户房屋信息");
        }
        BuildHouseUserDAO houseUser = houseUserList.get(0);

        UserV1 user = userService.getById(addRequest.getUserId());

        addRequest.setParkId(user.getParkId());
        addRequest.setAreaId(houseUser.getAreaId());
        addRequest.setBuildingId(houseUser.getBuildingId());
        addRequest.setVisitorName(request.getName());
        addRequest.setVisitorPhone(request.getPhone());
        addRequest.setFaceKey(request.getFaceKey());
        addRequest.setFaceUrl(request.getFaceUrl());
        addRequest.setGender(request.getGender());
        addRequest.setVerifyType(VisitorConstants.VerifyType.OWNER);

        AjaxResult result = visitorBizService.addVisitor(addRequest);
        if (AjaxResult.isError(result)) {
            return result;
        }

        redisService.deleteObject("inviteVisitor:" + request.getVisitorId());

        return result;
    }
}
